package 基本线程机制.新类库中的构件;

import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;
import static net.mindview.util.Print.*;
public class priorityBlockingQueueDemo {//praɪ'ɒrɪtɪ 优先级队列。
	public static void main(String[] args) {
		ExecutorService exec=Executors.newCachedThreadPool();
		PriorityBlockingQueue<Runnable> queue=new PriorityBlockingQueue<>();
		exec.execute(new PrioritizedTaskProducer(queue, exec));
		exec.execute(new PrioritizedTaskConsumer(queue));
	}
}
class PrioritizedTask implements Runnable,Comparable<PrioritizedTask>{
	private Random rand=new Random(47);
	private static int counter=0;
	private final int id=counter++;
	private final int priority;//优先级
	protected static List<PrioritizedTask> sequence=new ArrayList<>();
	public PrioritizedTask(int priority){
		this.priority=priority;
		sequence.add(this);
	}
	public int compareTo(PrioritizedTask arg) {
		// TODO Auto-generated method stub
		return priority<arg.priority?1:(priority>arg.priority?-1:0);
	}
	
	public void run() {
		try{
			TimeUnit.MILLISECONDS.sleep(rand.nextInt(250));
		}catch (Exception e) {
			// TODO: handle exception
		}
		print(this);
	}
	public String toString(){
		return String.format("[%1$-3d]", priority)+" Task "+id;
	}
	public String summary(){
		return "("+id+":"+priority+")";
	}
	public static class EndSentinel extends  PrioritizedTask{
		private ExecutorService exec;
		public EndSentinel(ExecutorService e){
			super(-1);
			exec=e;
		}
		public void run(){
			int count=0;
			for(PrioritizedTask pt:sequence){
				printnb(pt.summary());
				if(++count%5==0){
					print();
				}
			}
			print();
			print(this+" Calling shutdownNow()");
			exec.shutdownNow();
		}
	}
}
class PrioritizedTaskProducer implements Runnable{//pri o ri ti zed  优先级
	private Random rand=new Random(47);
	private Queue<Runnable> queue;
	private ExecutorService exec;
	public  PrioritizedTaskProducer(Queue<Runnable> q,ExecutorService e) {
		this.queue=q;
		this.exec=e;
	}
	@Override
	public void run() {
		try{
			for(int i=0;i<20;i++){
				TimeUnit.MICROSECONDS.sleep(250);
				queue.add(new PrioritizedTask(rand.nextInt(10)));
			}
			for(int i=0;i<10;i++){
				queue.add(new PrioritizedTask(rand.nextInt(i)));
			}
			queue.add(new PrioritizedTask.EndSentinel(exec));
		}
		catch(Exception e){
		}
		print("Finished PrioritizedTaskProducer");
	}
}
class PrioritizedTaskConsumer implements Runnable{
	private PriorityBlockingQueue<Runnable> q;
	public PrioritizedTaskConsumer(PriorityBlockingQueue<Runnable> q){
		this.q=q;
	}
	public void run(){
		while(!Thread.interrupted()){
			try {
				q.take().run();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			print("Finished PrioritizedTaskConsumer");
		}
	}
}
